﻿#define Debug1
using System;
using System.Collections;
using System.Collections.Generic;
using System.Data;

using System.Web;
using System.Web.Services;
using System.Web.Services.Protocols;
using System.Xml;
using com.SyncConfiguration;
using System.Web.Script.Serialization;
//using SyncLogic;

namespace SyncServer
{
    /// <summary>
    /// Summary description for $codebehindclassname$
    /// </summary>
    [WebService(Namespace = "http://tempuri.org/")]
    [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)]
    public class Download : IHttpHandler
    {
        private const string EnabledMonitor = "EnabledMonitor";
        private const string RequestKey = "RequestKey";
        private const string SyncConfiguration = "SyncConfiguration";
        SyncServer.Log log = null;
        SyncLogManager logmanger = new SyncLogManager();
        private bool _EnableMonitor = false;

        public void ProcessRequest(HttpContext context)
        {
            if ("1".Equals(System.Configuration.ConfigurationManager.AppSettings[EnabledMonitor]))
            {
                log = new SyncServer.Log();
                _EnableMonitor = true;
            }
            String Host = context.Request.UserHostAddress;
            HttpResponse response = context.Response;
            response.Clear();
            context.Response.AddHeader("Content-Encoding", "gzip");
            response.ContentType = "text/plain;charset=UTF8";
         
            //获取请求
            byte[] requestData = new byte[1024];
            int length = context.Request.InputStream.Read(requestData, 0, requestData.Length);
            string RequestContent = System.Text.Encoding.UTF8.GetString(requestData, 0, length);
            System.IO.MemoryStream stream = new System.IO.MemoryStream();
            JavaScriptSerializer ser = new JavaScriptSerializer();
            RequestHeader header = ser.Deserialize<RequestHeader>(RequestContent);//解析请求参数对象
            if (header == null)
            {
                logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "参数解析错误", "", "", Environment.MachineName.ToString());
                MyWriter w = new MyWriter(stream, true);//是否压缩流
                w.Write("[" + DownloadModules.setJsonData("", 0, "", false, "参数解析错误", false).TrimEnd(',') + "]");
                w.Flush();
                w.Close();
                return;


            }
           
                MyWriter writer = new MyWriter(stream, header.Gzip);//是否压缩流
                //验证RequestKey
                string requestKey = System.Configuration.ConfigurationManager.AppSettings[RequestKey];
                String LocalKey = Jumpton.Common.Functions.EncryptString(header.UserToken + header.Version + requestKey);
                if (!LocalKey.Equals(header.Requestkey))
                {
                    string err = "安全验证不匹配";
                    //记录数据库日志
                    logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, err, "", header.UserToken, Environment.MachineName.ToString());
                    writer.Write("["+DownloadModules.setJsonData("", 0, "", false, err, false).TrimEnd(',')+"]");
                }
                else
                {
                    SyncConfigurationSection config = null;
                    //验证版本是否正确
                    Dictionary<string, SyncConfigurationSection> syncConfig = context.Cache[SyncConfiguration] as Dictionary<string, SyncConfigurationSection>;
                    if (syncConfig != null && syncConfig.ContainsKey(header.Version))
                        config = syncConfig[header.Version];

                    bool LoginAuthorization = false;
                    if (log != null)
                        log.Send(string.Format("{3}  远程主机：{0} , 用户验证Token:{1}, 版本：{2}", Host, header.UserToken, header.Version, DateTime.Now));
                    //首先对用户进行验证，如果验证失败输出"z",如果执行出错以"error:出错信息"格式输出内容
                    string content = "";
                    string tableName = "";

                    try
                    {
                        if (config == null) //如果该版本的配置不存在
                        {
                            //记录日志
                            if (log != null)
                                log.Send(string.Format("版本号{0}不存在", header.Version));
                            //记录数据库日志
                            logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, string.Format("版本号{0}不存在", header.Version), "", header.UserToken, Environment.MachineName.ToString());
                            writer.Write("[" + DownloadModules.setJsonData("", 0, "", false, "版本号" + header.Version  + "错误", false).TrimEnd(',') + "]");
                            writer.Finish();
                        }
                        else
                        {
                            //获取对象实例
                            System.Reflection.Assembly assembly = System.Reflection.Assembly.LoadFile(config.FullPath);
                            SyncInterface.IValidate instance = null;
                            instance = Activator.CreateInstance(assembly.GetType(config.Type.FullName)) as SyncInterface.IValidate;
                            if (instance == null)
                            {
                                logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "接口类型转换失败！", "", header.UserToken, Environment.MachineName.ToString());
                                DownloadModules.setJsonData("", 0, tableName, false, "接口类型转换失败!", false);
                                return;
                            }
                            LoginAuthorization = instance.Authorization(header.UserToken);
                            //认证通过
                            if (LoginAuthorization)
                            {
                                try
                                {
                                  
                                    //从请求内容中获取客户端上传的需要下载的表以及时间戳
                                    foreach (string str in header.Tables)
                                    {
                                        
                                        try
                                        {
                                            
                                            tableName = str.Split(',')[0];
                                            decimal TimeStamp = Convert.ToInt64(str.Split(',')[1]);
                                            using (System.Data.IDbCommand command = instance.Connection.CreateCommand())
                                            {
                                                int start = Environment.TickCount;
                                                //获取下载数据
                                                #region 获取下载数据
                                                object o = instance.GetSyncLogicSQL(tableName, SyncInterface.AccessTypeClass.AccessType.Download, TimeStamp);
                                                //object o = config.Type.InvokeMember("GetSyncLogicSQL", System.Reflection.BindingFlags.InvokeMethod, Type.DefaultBinder, instance, new object[] { tableName, SyncLogic.AccessTypeClass.AccessType.Download, TimeStamp });
                                                if (o == null)
                                                {
                                                    //记录数据库日志
                                                    logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "表名:" + tableName + " 没有找到对应获取逻辑方法.", "", header.UserToken, Environment.MachineName.ToString());
                                                    continue;
                                                }
                                                command.CommandText = o.ToString();
                                                if (string.IsNullOrEmpty(command.CommandText))
                                                {
                                                    //记录数据库日志
                                                    logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "表名:" + tableName + " 没有获取到逻辑SQL.", "", header.UserToken, Environment.MachineName.ToString());
                                                    continue;
                                                }

                                                if (instance.Connection != null && instance.Connection.State != ConnectionState.Open)
                                                {
                                                    instance.Connection.Open();
                                                }
                                                IDataReader reader = command.ExecuteReader();
                                                #endregion
                                                if (log != null)
                                                    log.Send(tableName + "获取数据:" + (Environment.TickCount - start).ToString());

                                                //输出获取的下载数据
                                                content += DownloadModules.GeneractorContentToJson(reader, tableName);
                                                if (log != null)
                                                    log.Send(tableName + "封装数据数据:" + (Environment.TickCount - start).ToString());

                                            }
                                        }
                                        catch (Exception ex)
                                        {
                                            content += DownloadModules.setJsonData("", 0, tableName, false, "下载失败，" + ex.Message,true);
                                            //记录数据库日志
                                            logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "表:" + tableName + "下载失败," + ex.Message, "", header.UserToken, Environment.MachineName.ToString());
                                        }

                                    }
                                    content = "[" + content.TrimEnd(',') + "]";
                                    //response.Write(CompressionHelper.Compress(content));
                                    //return;
                                    writer.Write(content);
                                    writer.Flush();
                                }
                                catch (Exception exx)
                                {
                                    content += DownloadModules.setJsonData("", 0, tableName, false, "下载失败，" + exx.Message, false);
                                    content = "[" + content.TrimEnd(',') + "]";
                                    writer.Write(content);
                                    //记录数据库日志
                                    logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "下载失败," + exx.Message, "", header.UserToken, Environment.MachineName.ToString());
                                }
                                finally
                                {
                                    if (instance.Connection != null && instance.Connection.State == ConnectionState.Open)
                                    {
                                        instance.Connection.Close();
                                        instance.Connection.Dispose();
                                        instance = null;
                                    }
                                }
                            }
                            else
                            {
                                if (log != null)
                                    log.Send(DateTime.Now.ToString() + " 验证失败");
                                //密码或者用户名不存在，暂时为了测试方便以“error:PasswordOrUserError”
                                content = "[" + DownloadModules.setJsonData("", 0, tableName, false, "用户名或者密码错误", false).TrimEnd(',') + "]";
                                writer.Write(content);

                                //记录数据库日志
                                logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, "用户:" + header.UserToken + " 登录验证失败，用户名或者密码错误！", "", header.UserToken, Environment.MachineName.ToString());
                            }


                        }
                    }
                    catch (OutOfMemoryException err)
                    {
                        GC.Collect();
                        stream = new System.IO.MemoryStream();
                        writer = new MyWriter(stream);
                        writer.Write("内存溢出");
                        if (log != null)
                            log.Send(string.Format("{1} 同步错误:{0}", err.Message, DateTime.Now.ToString()));
                        //记录数据库日志
                        logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, string.Format("同步错误:{0}", err.Message), "", header.UserToken, Environment.MachineName.ToString());
                    }
                    catch (Exception err)
                    {
                        stream = new System.IO.MemoryStream();
                        writer = new MyWriter(stream);
                        content = "[" + DownloadModules.setJsonData("", 0, tableName, false, err.Message, false).TrimEnd(',') + "]";
                        writer.Write(content);
                        if (log != null)
                            log.Send(string.Format("{1} 同步错误:{0}", err.Message, DateTime.Now.ToString()));
                        //记录数据库日志
                        logmanger.AddLog(LogType.USER_SYNC_DOWNLOAD, string.Format("同步错误:{0}", err.Message), "", header.UserToken, Environment.MachineName.ToString());
                    }
                }
            
            
            writer.Flush();
            writer.Finish();
            if (stream.Length > 0)
            {
                stream.Position = 0;
                stream.WriteTo(response.OutputStream);
            }
            writer.Close();
            if (log != null)
                log.Close();
            writer = null;
        }

        public bool IsReusable
        {
            get
            {
                return false;
            }
        }
    }
}
